#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <atomic>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/time.h>
#include <boost/algorithm/string.hpp>
namespace FileTool
{

    static const std::string &temp_file_path = "./temp/";

    class FileSplice
    {
    public:
        //Add Suffix
        static std::string AddSuffix(const std::string &filename, const std::string &suffix)
        {
            std::string real_filename = temp_file_path; //   ./temp/
            real_filename += filename;                  //  ./temp/xxx
            real_filename += suffix;                    //  ./temp/xxx.cpp || ./temp/xxx.exe || ./temp/xxx.stderr
            return real_filename;
        }

    public:
        // 编译模块--文件拼接
        static std::string SpliceSrcPathName(const std::string &filename)
        {
            return AddSuffix(filename, ".cpp");
        }

        static std::string SpliceExePathName(const std::string &filename)
        {
            return AddSuffix(filename, ".exe");
        }
        static std::string SpliceCompileStderrLog(const std::string &filename)
        {
            return AddSuffix(filename, ".stderr");
        }

        // run的拼接模块
        static std::string SpliceRunStdin(const std::string &filename)
        {
            return AddSuffix(filename, ".stdin");
        }
        static std::string SpliceRunStdout(const std::string &filename)
        {
            return AddSuffix(filename, ".stdout");
        }
        static std::string SpliceRunStderr(const std::string &filename)
        {
            return AddSuffix(filename, ".stderr");
        }
    };

    // 判断文件是否存在
    class FileIsExists
    {
    public:
        static bool IsFileExists(const std::string &file)
        {
            struct stat st;
            int res = stat(file.c_str(), &st);
            return res == 0 ? true : false;
        }
    };

    class TimeUtil
    {
    public:
        //获取毫秒时间戳
        static std::string SetTimeMs()
        {
            struct timeval time_ms;
            gettimeofday(&time_ms, nullptr);
            return std::to_string(time_ms.tv_sec * 1000 + time_ms.tv_usec / 1000);
        }
    };
    class UniqueFileName
    {
    public:
        static std::string SetUniqueFileName()
        {
            std::atomic_uint id(0);
            ++id;
            std::string curr_ms = TimeUtil::SetTimeMs();
            std::string uid = std::to_string(id);
            return curr_ms + "_" + uid;
        }
    };
    class RWFile
    {
    public:
        static bool WriteDataToFile(const std::string &file, const std::string &data)
        {
            std::ofstream wr(file);
            if(!wr.is_open())
            {
                return false;
            }
            wr.write(data.c_str(),data.size());
            //也可以使用<<
            wr.close();
            return true;
        }
        static bool ReadDataToFile(const std::string &file,std::string* out,bool keep = false)
        {
            std::ifstream rd(file);
            if(!rd.is_open())
            {
                return false;
            }
            //getline不保存行分隔符！
            std::string line;
            while(std::getline(rd,line))
            {
                (*out) += line;
                //根据上层调用判断是否需要添加\n;
                (*out) += (keep ? "\n" : "");
            }
            return true;
        }
    };
    //字符串切分
    class StringUtil
    {
    public:
        static void SepString(const std::string prevstr,std::vector<std::string>* res,std::string sep)
        {
            //开启分隔符压缩：boost::algorithm::token_compress_on  --多个sep连接在一起压缩为一个sep
            boost::split(*res,prevstr,boost::is_any_of(sep),boost::algorithm::token_compress_on);
        }
    };
}
